package com.mky.mkcompany.service;

import com.alibaba.fastjson.JSONObject;
import com.mky.mkcompany.authorization.manager.TokenManager;
import com.mky.mkcompany.authorization.model.TokenModel;
import com.mky.mkcompany.controller.domain.UserRequest;
import com.mky.mkcompany.dao.AdminUserDao;
import com.mky.mkcompany.dao.UserDao;
import com.mky.mkcompany.dao.UserExamTypeDao;
import com.mky.mkcompany.dic.UserCheckDic;
import com.mky.mkcompany.dic.UserLoginDic;
import com.mky.mkcompany.dic.UserStatusDic;
import com.mky.mkcompany.exception.WafException;
import com.mky.mkcompany.model.AdminUser;
import com.mky.mkcompany.model.User;
import com.mky.mkcompany.model.UserExamType;
import com.mky.mkcompany.tool.DateUtil;
import com.mky.mkcompany.tool.EncryptUtil;
import com.mky.mkcompany.tool.PasswordUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.sql.Timestamp;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by Administrator on 2016/10/26.
 */
@Service
public class LoginOutService {
    private final Logger LOGGER = LoggerFactory.getLogger(getClass());
    @Autowired
    private UserDao userDao;
    @Autowired
    private RedisTemplate<String, AtomicInteger> redis;
    @Autowired
    private TokenManager tokenManager;

    @Autowired
    private UserExamTypeDao userExamTypeDao;

    @Autowired
    private AdminUserDao adminUserDao;


    public JSONObject   loginV2(UserRequest userRequest){

        JSONObject res=new JSONObject();
        String username=userRequest.getUsername();
        String passwords=userRequest.getPassword();
        AdminUser user = adminUserDao.findByUsername(username);
        if (user == null) {
            //提示用户名或密码错误
            throw new WafException("username or password error!","用户名或密码错误",
                    HttpStatus.NOT_ACCEPTABLE);
        }
        //判断用户是否被禁用
        int valid=user.getValid();
        if(valid== UserStatusDic.DISABLE){//禁用
            throw new WafException("","你的账户已欠费，已被禁用，请续费",
                    HttpStatus.NOT_ACCEPTABLE);
        }
        //retry count + 1
        AtomicInteger retryCount = redis.opsForValue().get(UserLoginDic.PROJ_NAME_USERNAME+username);
        if(retryCount == null) {
            retryCount = new AtomicInteger(0);
            redis.boundValueOps(UserLoginDic.PROJ_NAME_USERNAME+username).set(retryCount, UserLoginDic.RETRY_COUNT_EXPIRES_MINUTES, TimeUnit.MINUTES);
        }
        int retryTime = retryCount.incrementAndGet();
        redis.boundValueOps(UserLoginDic.PROJ_NAME_USERNAME+username).set(retryCount, UserLoginDic.RETRY_COUNT_EXPIRES_MINUTES, TimeUnit.MINUTES);
        String password=userRequest.getPassword();
        password= PasswordUtil.encryptPassword(password, user.getSalt());
        boolean matches=password.equals(user.getPassword());
        if (!matches) {
            if(retryTime > UserLoginDic.MAX_RETRY_TIMES){
                throw new WafException("password errors too much!","密码错误次数过多,1分钟后重试！",
                        HttpStatus.NOT_ACCEPTABLE);
            }else{
                //提示用户名或密码错误
                int remainTime= UserLoginDic.MAX_RETRY_TIMES-retryTime+1;
                throw new WafException("username or password error!","用户名或密码错误，你还有"+remainTime+"次重试机会",
                        HttpStatus.NOT_ACCEPTABLE);
            }
        }
        // clear retry count
        redis.delete(UserLoginDic.PROJ_NAME_USERNAME+username);
        TokenModel model = tokenManager.createToken(String.valueOf(user.getId()),username);
        String token=model.getUserId()+"_"+model.getToken();
        //token= EncryptUtil.encrypt(token);
        res.put("token",token);
        res.put("userInfo",user);
        res.put("success",true);
        res.put("status",200);
        res.put("message","登录成功");
        return res;
    }

    public JSONObject   login(UserRequest userRequest){

        JSONObject res=new JSONObject();
        String username=userRequest.getUsername();
        User user = userDao.findUserByUsername(username);
        if (user == null) {
            //提示用户名或密码错误
            throw new WafException("username or password error!","用户名或密码错误",
                    HttpStatus.NOT_ACCEPTABLE);
        }
        //判断用户是否被禁用
        Integer valid=user.getValid();
        if(valid== UserStatusDic.DISABLE){//禁用
            throw new WafException("","你的账户已欠费，已被禁用，请续费",
                    HttpStatus.NOT_ACCEPTABLE);
        }
        //retry count + 1
        AtomicInteger retryCount = redis.opsForValue().get(UserLoginDic.PROJ_NAME_USERNAME+username);
        if(retryCount == null) {
            retryCount = new AtomicInteger(0);
            redis.boundValueOps(UserLoginDic.PROJ_NAME_USERNAME+username).set(retryCount, UserLoginDic.RETRY_COUNT_EXPIRES_MINUTES, TimeUnit.MINUTES);
        }
        int retryTime = retryCount.incrementAndGet();
        redis.boundValueOps(UserLoginDic.PROJ_NAME_USERNAME+username).set(retryCount, UserLoginDic.RETRY_COUNT_EXPIRES_MINUTES, TimeUnit.MINUTES);
        String password=userRequest.getPassword();
        password= PasswordUtil.encryptPassword(password, user.getSalt());
        boolean matches=password.equals(user.getPassword());
        if (!matches) {
            if(retryTime > UserLoginDic.MAX_RETRY_TIMES){
                throw new WafException("password errors too much!","密码错误次数过多,1分钟后重试！",
                        HttpStatus.NOT_ACCEPTABLE);
            }else{
                //提示用户名或密码错误
                int remainTime=UserLoginDic.MAX_RETRY_TIMES-retryTime+1;
                throw new WafException("username or password error!","用户名或密码错误，你还有"+remainTime+"次重试机会",
                        HttpStatus.NOT_ACCEPTABLE);
            }
        }
        // clear retry count
        redis.delete(UserLoginDic.PROJ_NAME_USERNAME+username);
        TokenModel model = tokenManager.createToken(user.getId(),username);
        String token=model.getUserId()+"_"+model.getToken();
        //token= EncryptUtil.encrypt(token);
        //记录用户首次登录时间和更新最近一次登录时间
        Timestamp timestamp= DateUtil.getNowTimestamp();
        if(user.getFirstLoginTime()==null){
            user.setFirstLoginTime(timestamp);
        }
        user.setLastLoginTime(timestamp);
        userDao.save(user);

        UserExamType userExamType=userExamTypeDao.findByUserId(user.getId());
        String examType="";
        if(userExamType==null){
            examType="护士执业";
        }else {
            examType=userExamType.getExamType();
        }
        res.put("examType",examType);
        res.put("token",token);
        res.put("userInfo",user);
        res.put("success",true);
        res.put("status",200);
        res.put("message","登录成功");
        return res;
    }
}
